
//协议相当于Java里面的接口

protocol ExampleProtocol{
	var simpleDescription:String{
		get
	}
	
	mutating func adjust()
}

// 类、枚举、结构体 都可以使用协议

class SimpleClass:ExampleProtocol{
	var simpleDescription :String = "A very simple class."
	
	var anotherProperty:Int = 69105
	
	func adjust(){
		simpleDescription += " Now 100% adjusted"
	}
}

var a:SimpleClass = SimpleClass()

a.adjust()

let aDesc = a.simpleDescription

print(aDesc)

//简单的结构体

struct SimpleStructure:ExampleProtocol{
	var simpleDescription:String = "A simple structure"
	
	//实现协议的方法
	mutating func adjust() {
		simpleDescription += " (adjusted)"
	}
	
}

var b:SimpleStructure = SimpleStructure()

b.adjust()

let bDesc = b.simpleDescription

print(bDesc)

enum SimpleEnum:String,ExampleProtocol{
	case one,two
	//enums may not contain stored properties
	var simpleDescription:String {// read only
		get{
			switch self{
				case .one:
					return "A simple enum one adjust"
				case .two:
					return "A simple enum two adjust"
			}

		}
		
//		set {
//				simpleDescription = newValue
//		}
	}
	
	mutating func adjust() {
		print(simpleDescription)
	}

}

var e:SimpleEnum = SimpleEnum.two
//e.simpleDescription = "simple enum "
print(e.simpleDescription)


//扩展

extension Int : ExampleProtocol{
	var simpleDescription: String{
		return "The number \(self)"
	}
	
	mutating func adjust(){
		self += 42
	}
}

var inte:Int = 12;
inte.adjust()
print("It's a adjust int value is \(inte)")

//多态的形式

let protocolValue : ExampleProtocol = a

print(protocolValue.simpleDescription)

//print(protocolValue.anotherProperty)

enum PrinterError: ErrorType {
	case outOfPaper
	case noToner
	case onFire
}

enum OtherError: ErrorType {
	case otherError
	case unknownError
}

func send(job:Int,toPrinter printerName:String) throws -> String{
	if(printerName == "Never Has Toner"){
		throw  PrinterError.noToner
	}else if(printerName == "Other"){
		throw OtherError.otherError
	}
	return "Job sent"
}

do{
//	var printerResponse = try send(100,toPrinter :"Never Has Toner")
//	print("printer resonse : \(printerResponse)")
	
	var printerResponse = try send(100,toPrinter :"Other")
	
	print("printer resonse : \(printerResponse)")
	
}catch PrinterError.onFire{
	print("I'll just be put this over here,with the rest of the fire.")
}catch let printerError as PrinterError{
	print("PrinterError: \(printerError)")
}
catch{
	print("response error: \(error)")
}


//try?

var printerResponse = try? send(100,toPrinter :"Other")
print("printer resonse : \(printerResponse)")


var fridgeIsOpen = false
let fridgeContent = ["milk", "eggs", "leftovers"]
 
func fridgeContains(food: String) -> Bool {
	fridgeIsOpen = true
	defer {//推迟执行,在函数返回之前立即执行，无论函数是否异常
		print("fridgeIsOpen before:\(fridgeIsOpen)")
		fridgeIsOpen = false
		print("fridgeIsOpen after :\(fridgeIsOpen)")
	}
	
	let result = fridgeContent.contains(food)
	return result
}
fridgeContains("eggs")
print(fridgeIsOpen)











